package edu.uts.reekie.designer.model;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.views.properties.ComboBoxPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertyDescriptor;

import edu.uts.reekie.designer.ImageHelper;
import edu.uts.reekie.designer.Messages;

public class AbstractDiagram extends ViewNode {
	
	static final long serialVersionUID = 1;

	public static String ID_ROUTER = "router";	//$NON-NLS-1$
	public static Integer ROUTER_MANUAL = new Integer(0);
	public static Integer ROUTER_MANHATTAN = new Integer(1);
	public static Integer ROUTER_SHORTEST_PATH = new Integer(2);
	private static Image DIAGRAM_ICON = ImageHelper.createFromConceptualModelResource("icons/conceptual.gif"); //$NON-NLS-1$
	private static int count;


	protected List<ViewNode> children = new ArrayList<ViewNode>();
	protected Integer connectionRouter = null;
	private boolean rulersVisibility = false;
	private boolean snapToGeometry = false;
	private boolean gridEnabled = false;
	private double zoom = 1.0;

	public AbstractDiagram() {
		size.width = 100;
		size.height= 100;
		location.x = 20;
		location.y = 20;
	}

	public void addChild(ViewNode child){
		addChild(child, -1);
	}

	public void addChild(ViewNode child, int index){
		if (index >= 0)
			children.add(index,child);
		else
			children.add(child);
		fireChildAdded(CHILDREN, child, new Integer(index));
	}

	public List<ViewNode> getChildren(){
		return children;
	}

	public Integer getConnectionRouter(){
		if(connectionRouter==null)
			connectionRouter = ROUTER_MANUAL;
		return connectionRouter;
	}

	public Image getIconImage() {
		return DIAGRAM_ICON;
	}

	public String getNewID() {
		return Integer.toString(count++);
	}

	public double getZoom() {
		return zoom;
	}

	/**
	 * Returns <code>null</code> for this model. Returns
	 * normal descriptors for all subclasses.
	 *
	 * @return  Array of property descriptors.
	 */
	public IPropertyDescriptor[] getPropertyDescriptors() {
		if(getClass().equals(AbstractDiagram.class)){
			ComboBoxPropertyDescriptor cbd = new ComboBoxPropertyDescriptor(
					ID_ROUTER, 
					Messages.PropertyDescriptor_LogicDiagram_ConnectionRouter,
					new String[]{
						Messages.PropertyDescriptor_LogicDiagram_Manual,
						Messages.PropertyDescriptor_LogicDiagram_Manhattan,
						Messages.PropertyDescriptor_LogicDiagram_ShortestPath});
			cbd.setLabelProvider(new ConnectionRouterLabelProvider());
			return new IPropertyDescriptor[]{cbd};
		}
		return super.getPropertyDescriptors();
	}

	public Object getPropertyValue(Object propName) {
		if(propName.equals(ID_ROUTER))
			return connectionRouter;
		return super.getPropertyValue(propName);
	}



	public boolean getRulerVisibility() {
		return rulersVisibility;
	}

	public boolean isGridEnabled() {
		return gridEnabled;
	}

	public boolean isSnapToGeometryEnabled() {
		return snapToGeometry;
	}

	private void readObject(java.io.ObjectInputStream s)
			throws IOException, ClassNotFoundException {
		s.defaultReadObject();
	}
	public void removeChild(ViewNode child){
		children.remove(child);
		fireChildRemoved(CHILDREN, child);
	}

	public void setConnectionRouter(Integer router){
		Integer oldConnectionRouter = connectionRouter;
		connectionRouter = router;
		firePropertyChange(ID_ROUTER, oldConnectionRouter, connectionRouter);
	}

	public void setPropertyValue(Object id, Object value){
		if(ID_ROUTER.equals(id))
			setConnectionRouter((Integer)value);
		else super.setPropertyValue(id,value);
	}

	public void setRulerVisibility(boolean newValue) {
		rulersVisibility = newValue;
	}

	public void setGridEnabled(boolean isEnabled) {
		gridEnabled = isEnabled;
	}

	public void setSnapToGeometry(boolean isEnabled) {
		snapToGeometry = isEnabled;
	}

	public void setZoom(double zoom) {
		this.zoom = zoom;
	}

	public String toString(){
		return Messages.LogicDiagram_LabelText;
	}

	private class ConnectionRouterLabelProvider 
		extends org.eclipse.jface.viewers.LabelProvider{

		public ConnectionRouterLabelProvider(){
			super();
		}
		public String getText(Object element){
			if(element instanceof Integer){
				Integer integer = (Integer)element;
				if(ROUTER_MANUAL.intValue()==integer.intValue())
					return Messages.PropertyDescriptor_LogicDiagram_Manual;
				if(ROUTER_MANHATTAN.intValue()==integer.intValue())
					return Messages.PropertyDescriptor_LogicDiagram_Manhattan;
				if(ROUTER_SHORTEST_PATH.intValue()==integer.intValue())
					return Messages.PropertyDescriptor_LogicDiagram_ShortestPath;
			}
			return super.getText(element);
		}
	}

}
